import { KeyVoUtil, IKeyVo} from "../utils/KeyVoUtil";
import { ValueUtil } from "../utils/ValueUtil";
import { ITableObj, IPlugIn, ITableJson, ITableData, IConvertParser } from "../../inters/InterfaceApi";
import { Convert } from "../Convert";
import { convertMgr } from "../mgr/ConvertMgr";
import { errLogMgr } from "../mgr/ErrLogMgr";
import { ICls, IInterface } from "../utils/ClsFactory";
import { TypeUtil } from "../utils/TypeUtil";
import { codeMgr } from "../mgr/CodeMgr";
import { langMgr } from "../mgr/LanguageMgr";
import { Pinyin } from "../../pinyin/Pinyin";

export class BaseParser implements IPlugIn, IConvertParser {

    convert: Convert;

    protected _clsList: Array<ICls>;
    protected _errLogs: string[];
    protected _langkeys: Array<IKeyVo>;
    protected _primaryKeys: string[] = [];
    protected _cacheData: any;
    private _data:ITableObj;

    start(data: any, options?: any, callback?: (res?: any) => void) {
       this._data=data;
        return this;
    }

    parseValue(){
        this.convert = convertMgr.crtConvert;
        this._errLogs = []
        this._cacheData = {};
        let tableData: ITableObj = this._data;
        let keys = tableData.data[0];
        let descs = tableData.data[1];
        let keyVos: IKeyVo[] = []
        this._primaryKeys = [];
        let enumkey: IKeyVo;
        this._langkeys = [];
        this._clsList = [];
        let tp = this.convert.convertCfg.tsOption.tablePrefix
        var iInter = new IInterface(tp + tableData.fileName);

        keys.forEach((keyStr, idx) => {
            let keyVo = KeyVoUtil.parserKey(keyStr, tableData.fileName);
            keyVo.des = descs[idx];
            if (keyVo.primaryKey) {
                this._primaryKeys.push(keyVo.name);
            }
            keyVos.push(keyVo)
            if (keyVo.content.lang) {
                this._langkeys.push(keyVo);
            }
            // 类型相关，之后都要用单独模块来处理，先简单拷贝过来用
            if (keyVo.enum) {
                if (keyVo.type === 'Array<enum>' || keyVo.type == 'enum[]') {
                    this._clsList.push(keyVo.enum);
                    iInter.addVar(keyVo.name, `Array<${keyVo.enum.name}>`, keyVo.des);
                } else {
                    this._clsList.push(keyVo.enum);
                    iInter.addVar(keyVo.name, keyVo.enum.name, keyVo.des);
                }
            } else if (keyVo.tags) {
                this._clsList.push(keyVo.tags);
                iInter.addVar(keyVo.name, TypeUtil.getType(keyVo.type), keyVo.des);
            } else if (keyVo.enumkey) {
                enumkey = keyVo;
                this._clsList.push(keyVo.enumkey);
            } else {
                iInter.addVar(keyVo.name, TypeUtil.getType(keyVo.type), keyVo.des, keyVo.primaryKey);
            }
        })
        this._clsList.push(iInter);
        let tableJson: ITableJson = {
            primaryKey: this._primaryKeys.join(','),
            langKeys: this._langkeys.map(lk => lk.name),
            list: []
        }
        for (let i = 2; i < tableData.data.length; i++) {
            let tds = tableData.data[i];
            if (tds.length <= 0) continue;
            let td = {};
            var key: string = "";
            var itemLang: any = {};
            keyVos.forEach((kv, idx) => {
                if (kv.content.exclude) {
                    return;
                }
                let value;
                try {
                    value = td[kv.name] = ValueUtil.parserValue(tds[idx], kv);
                } catch (e) {
                    this._errLogs.push(tableData.fileName + ":" + tds[0] + ":" + i + "---" + kv.name + "--数据错误:" + e.message);
                }
                if (kv.content.lang) {
                    let newkey = kv.name + '_' + kv.content.lang;
                    if (itemLang[newkey]) {
                        throw new Error("重复数据");
                    }
                    itemLang[newkey] = value;
                }
            })

            key = KeyVoUtil.getRealKey(td, this._primaryKeys);
            if (key === "") {
                key = i.toString();
            }
            this._cacheData[key] = td;

            if (enumkey) {
                let keyValue = td[enumkey.name];
                let pinyinKey = keyValue ? Pinyin.Inst.getFullChars(keyValue) : "";
                if (keyValue) {
                    enumkey.enumkey.addVar(pinyinKey, key, keyValue);
                }
                delete td[enumkey.name];
            }


            var tableName = tableData.fileName
            for (let j = 0; j < this._langkeys.length; j++) {
                let keyVo = this._langkeys[j];
                let newkey = keyVo.name + '_' + keyVo.content.lang;
                td[keyVo.name] = itemLang[newkey];
                let tempLangKey = tableName + "_" + key + "_" + keyVo.name
                langMgr.addLang(td[keyVo.name], tempLangKey, keyVo.content.lang, keyVo.content.font);
                delete td[keyVo.name];
                delete itemLang[newkey];
            }

            tableJson.list.push(td);
        }

        let tempTableData: ITableData = {
            type: "base",
            keys: keyVos,
            tableName: tableData.fileName,
            data: tableJson,
            errLog: this._errLogs,
            plat: tableData.platName
        }
        this.convert.addTableData(tempTableData, tableData.fileName, tableData.platName);

        errLogMgr.addLog(this._errLogs)
        codeMgr.addCls(this._clsList);
    }

    getData(key: string) {
        return this._cacheData[key];
    }

    get order(){return 0;}
}